/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * SpeakingFrm.java
 *
 * Created on 2011-12-1, 15:36:53
 */
package com.edu.kamai.client;

import com.edu.kamai.client.control.paperAnswerControl;
import com.edu.kamai.client.download.fileDownload;
import com.edu.kamai.client.upload.UploadMP3;
import com.edu.kamai.client.upload.UploadPaper;
import com.edu.kamai.config.Constant;
import com.edu.kamai.media.audio.AudioPlayer;
import com.edu.kamai.media.audio.wavRecord;
import com.edu.kamai.utility.FileName;
import com.edu.kamai.utility.TimeFormat;
import com.edu.kamai.xml.beans.speaking.speakingAnswer;
import com.edu.kamai.xml.beans.speaking.speakingQuestion;
import com.edu.kamai.xml.beans.speaking.speakingXML;
import com.edu.kamai.xmlparser.answerGeneration;
import com.edu.kamai.xmlparser.speaking.speakingAnswerGeneration;
import com.edu.kamai.xmlparser.speaking.speakingAnswerParser;
import com.edu.kamai.xmlparser.speaking.speakingPaperParser;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.swing.Timer;

/**
 *
 * @author xyzhu
 */
public class SpeakingFrm extends javax.swing.JFrame {

    /** Creates new form SpeakingFrm */
    public SpeakingFrm(ContestFrm cf,String sn,String pp,int pid,int cID) {
        identity = 0;
        contestFrm = cf;
        sutdentName = sn;
        paperPath = pp;
        paperID = pid;
        contestID = cID;
        initComponents();
        initPaper();
        initAnswerPaper();
        initQuestion(questionIndex);
        B_PlayRec.setEnabled(false);
        B_Next.setEnabled(false);
        
        speakingTimer = new Timer(1000, new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                speakingExeTime++;
                if(speakingExeTime >= speakingExeLimit){
                    passToNextQuestion();
                }
                uRecTime.setText(TimeFormat.retTimeFormatting(speakingExeTime));
            }
        });
        
        prepareTimer = new Timer(1000, new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                prepareExeTime++;
                if(prepareExeTime >= prepareExeLimit){
                    prepareTimer.stop();
                    TF_Status.setText("Now Speaking!");
                    RecWAV();
                }
                uPreTime.setText(TimeFormat.retTimeFormatting(prepareExeTime));
            }
        });
        
        
    }
    
    public SpeakingFrm(String tn,String pp,String app){
        identity = 1;
        paperPath = pp;
        answerPaperPath = app;
        initComponents();
        initAnswerPaper();
        initQuestion(questionIndex);
        B_Submit.setEnabled(false);
        B_Next.setEnabled(false);
        
        speakingTimer = new Timer(1000, null);
        prepareTimer = new Timer(1000, null);
        
    }
    
    private void setNet(){
        try{
            InputStream in = getClass().getResourceAsStream(Constant.netiniFilePath);
            Scanner scan = new Scanner(in);
            List<String> netList = new ArrayList<String>();
            
            while(scan.hasNextLine()){
                String line = scan.nextLine();
                if(!line.equals("")){
                    if(!line.startsWith("#")){
                        netList.add(line);
                    }
                }
            }
            paperAnswerControl.setNetList(netList);
            scan.close();
            in.close();
            
        }catch(Exception ex){
            ex.printStackTrace();
            //Control.setNetList(new ArrayList<String>());
        }
        paperAnswerControl.setServer();
    }
    
    private void showMessage(int ans,String msg){
        if(ans == 1){
            javax.swing.JOptionPane.showMessageDialog(this, msg, "Done", ans);
        }else{
            javax.swing.JOptionPane.showMessageDialog(this, msg, "Error", ans);
        }
    }
    
    private void initPaper(){
        spp = new speakingPaperParser(paperPath);
        sXml = spp.parseSpeakingXML();
        totalQuestionCnt = sXml.getSpeakingquestionList().size();
        questionIndex = 0;
    }
    
    private void initAnswerPaper(){
        if(0 == identity){
            sa = new speakingAnswer(totalQuestionCnt);
            sa.setPaperID(paperID);
            sa.setUserID(sutdentName);
        }else if(1 == identity){
            speakingAnswerParser wap = new speakingAnswerParser(answerPaperPath);
            sa = wap.parseWritingAnswerXML();
        }
    }
    
    private void judgeLocalFileExist(String fn){
        File file = new File(fn);
        while(file.exists() == false){
            try{
                Thread.sleep(500);
            }catch(Exception ex){
                ex.printStackTrace();
            }
        }
        B_Play.setEnabled(true);
        //B_Stop.setEnabled(true);
    }
    
    private void initQuestion(int index){
        B_Play.setEnabled(false);
        B_Next.setEnabled(false);
        prepareExeTime = 0;
        speakingExeTime = 0;
        speakingQuestion sq = sXml.getSpeakingquestionList().get(index);
        TF_Title.setText(sq.getPaperTitle());
        TA_Main.setText(sq.getMainTxt());
        prepareExeLimit = Integer.parseInt(sq.getPrepareTime());
        speakingExeLimit = Integer.parseInt(sq.getReadingTime());
        preTime.setText(TimeFormat.retTimeFormatting(prepareExeLimit));
        recTime.setText(TimeFormat.retTimeFormatting(speakingExeLimit));
        
        uPreTime.setText(TimeFormat.retTimeFormatting(prepareExeTime));
        uRecTime.setText(TimeFormat.retTimeFormatting(speakingExeTime));
        
        String mp3Path = sq.getMp3Path();
        if(!mp3Path.equals("") && mp3Path != null){
            String localName = downloadMP3(mp3Path);
            judgeLocalFileExist(localName);
        }
    }
    
    
    private String downloadMP3(String mp3Path){
        String url = Constant.urlAddress + "kamai_edu";
        url = url + mp3Path;
        int pos = mp3Path.lastIndexOf("/") + 1;
        String filename = FileName.getDefaultKamaiFolder() + mp3Path.substring(pos);
        localMp3Path = filename;
        File mp3 = new File(localMp3Path);
        if(!mp3.exists()){
            fileDownload fd = new fileDownload(url, filename);
            fd.start();
        }
        return filename;
    }
    
    private void upLoadAnwerPaper(){
        
        if(sa != null){
            String answerXMLName = "";
            answerGeneration axml = new speakingAnswerGeneration(sa);
            axml.generateXML();
            answerXMLName = FileName.reNameWithCurrentTime(sutdentName);
            System.out.println(answerXMLName);
            axml.writeToDisk(answerXMLName);

            UploadPaper upp = new UploadPaper();
            upp.setFileName(answerXMLName);
            upp.start();

            int ans = paperAnswerControl.addPaperAnswer(Constant.SPEAKING_PAPER_ID, 
                    Constant.upLoadPaperFileFolder + "/" + answerXMLName + ".xml", 
                    0, paperID, sutdentName, contestID);

            showMessage(ans, paperAnswerControl.getMessage());

            this.setVisible(false);
            contestFrm.setVisible(true);
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        TF_Title = new javax.swing.JTextField();
        B_Play = new javax.swing.JToggleButton();
        B_Submit = new javax.swing.JToggleButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        TA_Main = new javax.swing.JTextArea();
        B_Next = new javax.swing.JToggleButton();
        preTime = new javax.swing.JTextField();
        uPreTime = new javax.swing.JTextField();
        recTime = new javax.swing.JTextField();
        uRecTime = new javax.swing.JTextField();
        B_PlayRec = new javax.swing.JButton();
        TF_Status = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        TF_Title.setEditable(false);

        B_Play.setText("play");
        B_Play.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                B_PlayActionPerformed(evt);
            }
        });

        B_Submit.setText("submit");
        B_Submit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                B_SubmitActionPerformed(evt);
            }
        });

        TA_Main.setColumns(20);
        TA_Main.setEditable(false);
        TA_Main.setLineWrap(true);
        TA_Main.setRows(5);
        jScrollPane1.setViewportView(TA_Main);

        B_Next.setText("Next");
        B_Next.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                B_NextActionPerformed(evt);
            }
        });

        preTime.setEditable(false);

        uPreTime.setEditable(false);

        recTime.setEditable(false);

        uRecTime.setEditable(false);

        B_PlayRec.setText("play rec");
        B_PlayRec.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                B_PlayRecActionPerformed(evt);
            }
        });

        TF_Status.setEditable(false);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(TF_Title, javax.swing.GroupLayout.DEFAULT_SIZE, 409, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(B_Play, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(TF_Status, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addComponent(B_Next, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(B_Submit))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 409, Short.MAX_VALUE))
                .addGap(36, 36, 36)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addComponent(preTime)
                            .addComponent(recTime, javax.swing.GroupLayout.DEFAULT_SIZE, 52, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(uRecTime)
                            .addComponent(uPreTime, javax.swing.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE)))
                    .addComponent(B_PlayRec, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(27, 27, 27)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(preTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(uPreTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(TF_Title, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 268, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(B_Play)
                            .addComponent(B_Submit)
                            .addComponent(B_Next)
                            .addComponent(TF_Status, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(recTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(uRecTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(142, 142, 142)
                        .addComponent(B_PlayRec)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    
    private void upLoadRec(){
        //upload the local rec wav and modify the rec path
        UploadMP3 up = new UploadMP3();
        up.addMP3Path(localRecWavPath);
        String uploadPath = Constant.upLoadRECFileFolder + "/" + 
                FileName.reNameWithCurrentTime(localRecWavPath);
        sa.setSpeakingMp3Path(uploadPath);
        up.start();
    }   
    
    private void B_SubmitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_B_SubmitActionPerformed
        // TODO add your handling code here:
        upLoadAnwerPaper();
    }//GEN-LAST:event_B_SubmitActionPerformed

    private void PlayAudio(){
        String filename = localMp3Path;
        ap = new AudioPlayer(filename);
        ap.play();
        
        while(ap.isComplete() == false){
            try{
                Thread.sleep(500);
            }catch(Exception ex){
                ex.printStackTrace();
            }
        }
        prepareTimer.start();
        TF_Status.setText("Now Prepare!");
    }
    
    private void B_PlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_B_PlayActionPerformed
        // TODO add your handling code here:
        PlayAudio();
    }//GEN-LAST:event_B_PlayActionPerformed

    private void RecWAV(){
        B_Next.setEnabled(true);
        localRecWavPath = sutdentName + questionIndex + ".wav";
        System.out.println(localRecWavPath);
        wRec = new wavRecord(localRecWavPath);
        wRec.capture();
        //timer start
        speakingExeTime = 0;
        speakingTimer.start();
    }
    
    private void stopRec(){
        if(wRec != null){
            wRec.stop();
            wRec.save();
            wRec = null;
        }
        TF_Status.setText("");
    }
    
    private void passToNextQuestion(){
        speakingTimer.stop();
        stopRec();
        upLoadRec();
        
        questionIndex ++;
        if(questionIndex == totalQuestionCnt){
            showMessage(1, "You have finished All, You can submit the Answer!");
        }else{
            initQuestion(questionIndex);
        }
        
    }
    
    private void B_NextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_B_NextActionPerformed
        // TODO add your handling code here:
        passToNextQuestion();
    }//GEN-LAST:event_B_NextActionPerformed

    private void B_PlayRecActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_B_PlayRecActionPerformed
        // TODO add your handling code here:
        
        
    }//GEN-LAST:event_B_PlayRecActionPerformed

    
    private final Timer prepareTimer;
    private final Timer speakingTimer;
            
    private long prepareExeTime;
    private long speakingExeTime;
    private long prepareExeLimit;
    private long speakingExeLimit;
    
    private wavRecord wRec;
    private AudioPlayer ap;
    //private wavPlayer wma;
    //private mp3Player mp3;
   
    
    private int identity;
    private ContestFrm contestFrm;
    private String sutdentName;
    private String paperPath;
    private String localMp3Path;
    private String localRecWavPath;
    private int paperID;
    private int contestID;
    private int totalQuestionCnt;
    private int questionIndex;
    private String answerPaperPath;
    
    private speakingAnswer sa;
    private speakingPaperParser spp;
    private speakingXML sXml;
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JToggleButton B_Next;
    private javax.swing.JToggleButton B_Play;
    private javax.swing.JButton B_PlayRec;
    private javax.swing.JToggleButton B_Submit;
    private javax.swing.JTextArea TA_Main;
    private javax.swing.JTextField TF_Status;
    private javax.swing.JTextField TF_Title;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextField preTime;
    private javax.swing.JTextField recTime;
    private javax.swing.JTextField uPreTime;
    private javax.swing.JTextField uRecTime;
    // End of variables declaration//GEN-END:variables
}
